package com.yc.sole.framework.minio;

import io.minio.*;
import io.minio.http.Method;
import okhttp3.OkHttpClient;

import java.io.InputStream;
import java.util.concurrent.TimeUnit;

/**
 * @author yizuomin
 * @date 2024/1/3 09:29
 **/
public class MinioService {

    private final MinioClient client;
    private final MinIOProperties properties;

    public MinioService(MinIOProperties properties) {
        this.properties = properties;
        if (properties.getEndpoint() == null || "".equals(properties.getEndpoint())) {
            this.client = null;
        } else {
            OkHttpClient httpClient = new OkHttpClient.Builder()
                    .readTimeout(60, TimeUnit.SECONDS)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager())
                    .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                    .build();
            this.client = MinioClient.builder()
                    .endpoint(properties.getEndpoint())
                    .credentials(properties.getAccessKey(), properties.getSecretKey())
                    .httpClient(httpClient)
                    .build();
        }
    }


    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return url
     */
    public String getObjectURL(String bucketName, String objectName) {
        try {
            return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET)
                    .bucket(bucketName)
                    .expiry(10, TimeUnit.MINUTES)
                    .object(objectName).build());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public InputStream getFileAsInputStream(String bucketName, String objectName) {
        try {
            return client.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 上传文件
     *
     * @param bucketName  bucket名称
     * @param objectName  文件名称
     * @param stream      文件流
     * @param contextType 类型
     */
    public String putObject(String bucketName, String objectName, InputStream stream, String contextType) {
        int partSize = -1;
        try {
            boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            client.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(stream, stream.available(), partSize)
                    .contentType(contextType)
                    .build());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        return objectName;
    }

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     */
    public void removeObject(String bucketName, String objectName) {
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 获取文件原始链接
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    private String getResourceKey(String bucketName, String objectName) {
        return bucketName + "/" + objectName;
    }

    public String getResourceUrl(String resourceKey) {
        //获取配置
        String prefix = properties.getPrefix();
        StringBuilder resourceUrl = new StringBuilder(prefix);

        try {
            //截取签名
            int site = resourceKey.indexOf("/");
            String url = getObjectURL(resourceKey.substring(0, site), resourceKey.substring(site + 1));
            String sign = url.substring(url.indexOf("?"));
            //返回带签名的链接
            return resourceUrl.append("/").append(resourceKey).append(sign).toString();
        } catch (Exception e) {
            //出现异常，返回不带签名的链接
            return resourceUrl.append("/").append(resourceKey).toString();
        }
    }

    /**
     * 获取文件公用链接
     *
     * @param resourceKey
     * @return
     */
    public String getPubResourceUrl(String resourceKey) {
        //获取配置
        String prefix = properties.getPrefix();

        return prefix + "/" + resourceKey;
    }
}
